package br.com.cpqd.ssar.posprocessamento;


import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.StringTokenizer;
import java.util.Vector;



class readingAreaFFT {
    
    private FileInputStream fileInputStream;
    private FileChannel fileChannel;
    private long fileSize;
    private MappedByteBuffer mBuf;
    private Vector listCubeElements = new Vector();
    private CubeElement nCube;
    private Temporizador t;
    private char[] line = null;
    private String[] vline = null;
    private char temp;
    private int begin = 0; //inicio da linha
    private int cont=0;
    private Double maiorCampo = 0.0;
    private Double menorCampo = 0.0;
    private StringTokenizer st;
    private int numPassos, numMalha, sx, sy ,sz;
    private FileInputStream is;                 // Stream de Entrada
    private BufferedReader br;                  // Buffer de leitura
    private String substring;
    private boolean malha;                      //apenas para visualizar a cabe�a
    private Double cor;
    
    public readingAreaFFT(){
    }
    
    public Vector reading(String fileNameConfig, String fileNameMovie3d) throws FileNotFoundException, IOException{
        
        
        is = new FileInputStream(fileNameConfig);
        br = new BufferedReader(new InputStreamReader(is));
        String s;
        
        // lendo arquivo de configuracao 'nome do arquivo.config'
        try {
            
            //pula para a nona linha do arquivo
            for(int i=0; i<6; i++){
                s = br.readLine();
                System.out.println(String.valueOf(s));
            }
            
            s = br.readLine(); //le a primeira linha "Domain Properties"
            //apos dividir a linha, pega o valor 'sx'
            vline = split(s);
            sx = Integer.valueOf(vline[1]);
            System.out.println("sx: " + sx);
            
            //pegando o valor de 'sy'
            s = br.readLine();
            vline = split(s);
            sy = Integer.valueOf(vline[1]);
            System.out.println("sy: " + sy);
            
            //pegando o valor de 'sz'
            s = br.readLine();
            vline = split(s);
            sz = Integer.valueOf(vline[1]);
            System.out.println("sz: " + sz);
            
            // lendo Time Steps
            br.readLine();
            br.readLine();
            s = br.readLine();
            
            vline = split(s);
            numPassos = Integer.valueOf(vline[1]);
            
            numMalha = sx*sy*sz;
            
            System.out.println("Passos de tempo: " + numPassos);
            
            
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        is.close();
        br.close();
        
        Temporizador t = new Temporizador();
        // definindo maior e menor campo
        try {
            
            is = new FileInputStream(fileNameMovie3d);
            br = new BufferedReader(new InputStreamReader(is));
            
            //converte a linha de char para string
            while((s = br.readLine())!=null ){
                
                //divide essa string em x,y,z e campo
                vline = split(s);
                //define maior e menor campo para calcular 'range'
                if(maiorCampo < Double.valueOf(vline[3]))
                    maiorCampo = Double.valueOf(vline[3]);
                
                if(menorCampo > Double.valueOf(vline[3]))
                    menorCampo = Double.valueOf(vline[3]);
                
            }
            is.close();
            br.close();
            
        } catch (IOException exc) {
            System.out.println(exc);
            System.exit(1);
        }
        System.out.println("Tempo para definir maior e menor campo: " + t.toString());
        
        t = new Temporizador();
        
        //lendo o arquivo e criando malha 3D de resultados
        try {
            
            is = new FileInputStream(fileNameMovie3d);
            br = new BufferedReader(new InputStreamReader(is));
            
            //leitura do come�o ao fim do arquivo para 1 passo de tempo
            for(int j=0; j<numPassos*sx*sy*sz; j++) {
                
                s = br.readLine();
                //divide essa string em x,y,z e campo
                vline = split(s);
                //cria o novo cubo adquirido da n linha
                cor = setColorField(Double.valueOf(vline[3]));
                nCube = new CubeElement(Double.valueOf(vline[0]),Double.valueOf(vline[1]), Double.valueOf(vline[2]), cor);
                //System.out.println("cor: " + cor);
                //adiciona na lista de cubos
                //if (Float.valueOf(vline[3]) != 0.0)
                listCubeElements.add(nCube);
                
            }
            System.out.println("Tempo para ler arquivo de resultados: " + t.toString());
            System.out.println("Maior Campo: " + maiorCampo);
            System.out.println("Menor Campo: " + menorCampo);
            
        } catch (IOException exc) {
            System.out.println(exc);
            System.exit(1);
        }
        
        return listCubeElements;
        
        
    }
    
    
    
    public String[] split(String sentence) {
        //vetor que contem x,y,z e campo
        
        String[] tokens = null;
        
        String splitPattern = " ";
        
        tokens = sentence.split(splitPattern);
        
        if (tokens == null) {
            String msg = "   NO MATCH: pattern:" + sentence
                    + "\r\n             regex: " + splitPattern;
        } else
            return tokens;
        
        return tokens;
        
    }
    
    public Double setColorField(Double campo){
        
        Double range;
        Double passo;
        Double cor = 0.0;
        Double RGB = 255.0;
        
        // primeiro caso
        if(  (menorCampo < 0) && (maiorCampo > 0) && (campo < 0)   ) {
            
            range = Math.abs(menorCampo) + Math.abs(maiorCampo);
            passo = range / RGB; //rangeCor = 255 RGB
            cor = (Math.abs(menorCampo - campo)/passo)/255;
            
            
        }
        
        if(  (menorCampo < 0.0) && (maiorCampo > 0.0) && (campo > 0.0)   ) {
            range = Math.abs(menorCampo) + Math.abs(maiorCampo);
            passo = range/RGB;
            cor = (Math.abs(-menorCampo + campo)/passo)/255;
            
            
        }
        
        if(  (menorCampo > 0.0) && (maiorCampo > 0.0) && (campo > 0.0)   ) {
            range = maiorCampo - menorCampo;
            cor = (((Math.abs(campo - menorCampo) * RGB)/range) * (RGB/range))/255;
            
            
        }
        return cor;
        
    }
    
    
    public int[] getConfigMalha(){
        int[] configMalha = new int[2];
        configMalha[0] = this.numPassos;
        configMalha[1] = this.numMalha;
        return configMalha;
    }
    
}

